package com.dayu.tcp.protocol.codec;

import com.dayu.tcp.protocol.K1BaseMessage;
import com.dayu.tcp.protocol.K1RestfulRequest;
import com.dayu.tcp.protocol.K1RestfulResponse;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import lombok.Getter;

import java.util.List;

/**
 * @author yehangtech
 * @date 2025/4/6 16:26
 * @description K1协议编码器
 */
@ChannelHandler.Sharable
public class K1Encoder extends MessageToMessageEncoder<Object> {

    @Getter
    private static final K1Encoder singleton = new K1Encoder();

    private K1Encoder() {
    }

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Object obj, List<Object> list) {
        K1BaseMessage msg = null;
        if (obj instanceof K1RestfulRequest) {
            msg = K1RestfulRequest.requestTOK1BaseMessage((K1RestfulRequest) obj);
        } else if (obj instanceof K1RestfulResponse) {
            msg = K1RestfulResponse.responseTOK1BaseMessage((K1RestfulResponse) obj);
        }

        if (msg != null) {
            ByteBuf byteBuf = channelHandlerContext.alloc().buffer();
            // 1. 4 字节的魔数
            byteBuf.writeBytes(msg.getMagic());
            // 2. 4 字节的版本
            byteBuf.writeInt(msg.getVersion());
            // 3. 4 字节的数据包的业务标识
            byteBuf.writeInt(msg.getMessageType());
            // 4. 8 个字节的sequenceId
            byteBuf.writeLong(msg.getSequenceId());
            // 5. 1 字节的序列化方式
            byteBuf.writeByte(msg.getSerializerType());
            // 6. 1 字节的压缩方式
            byteBuf.writeByte(msg.getCompressType());
            // 7. 1 字节的加密方式
            byteBuf.writeByte(msg.getEncryptType());
            // 无意义，5字节对齐填充
            byteBuf.writeBytes(msg.getEmptyBytes());
            // 8. 获取内容的字节数组
            byte[] rawData = msg.getRawData();
            // 9. 4 字节的长度
            byteBuf.writeInt(rawData.length);
            // 10. 写入内容
            byteBuf.writeBytes(rawData);

            list.add(byteBuf);
        }
    }
}
